using System.Collections;
using System.Collections.Generic;

namespace SangsTools
{
    public abstract class PoolBase<T> : IPool<T>, IEnumerable<T> where T : IPoolMember
    {
        protected List<T> activeMembers;
        protected Stack<T> unActiveMembers;

        public int Count => activeMembers.Count;

        public PoolBase()
        {
            activeMembers = new List<T>();
            unActiveMembers = new Stack<T>();
        }

        public T GetMember()
        {
            T member;
            if (unActiveMembers.Count > 0)
                member = unActiveMembers.Pop();
            else
            {
                member = CreateMember();
                member.OnCreate();
            }

            member.OnGet();
            activeMembers.Add(member);
            return member;
        }

        protected abstract T CreateMember();

        public void Recycle(T member)
        {
            if (member == null) throw new System.Exception("can not recycle null");

            if (activeMembers.Contains(member))
                activeMembers.Remove(member);
            if (!unActiveMembers.Contains(member))
                unActiveMembers.Push(member);

            member.OnRecycle();
        }

        public void RecycleAll()
        {
            foreach (var member in activeMembers.ToArray())
            {
                Recycle(member);
            }
        }

        public void DestroyAll()
        {
            foreach (var item in activeMembers)
            {
                item.OnDestroy();
            }
            foreach (var item in unActiveMembers)
            {
                item.OnDestroy();
            }
            activeMembers.Clear();
            unActiveMembers.Clear();
        }

        public IEnumerator<T> GetEnumerator()
        {
            return activeMembers.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}